<?php

namespace App\Repository\Models;

use App\Services\Pay\CzbankService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use Prettus\Repository\Contracts\Transformable;
use Prettus\Repository\Traits\TransformableTrait;

/**
 * Class Order.
 *
 * @package namespace App\Repository\Models;
 */
class Orders extends Model implements Transformable
{
    use TransformableTrait;
    use SoftDeletes;

    protected $table = 'orders';
    protected $dates = ['created_at'];
    protected $appends = ['order_status_name', 'is_claim_invoice_name', 'cancel_reason_name'];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'user_id', 'shop_id', 'order_code', 'initial_product_money', 'product_money', 'initial_freight', 'freight', 'order_money', 'discount_money',
        'coupon_id', 'discount_coupons_money', 'order_status', 'order_type', 'refund_status', 'sales_return_status', 'pay_status', 'pay_method', 'pay_method_fee',
        'is_claim_invoice', 'courier_number', 'address', 'receiver', 'phone', 'order_at', 'pay_at', 'shipments_at', 'confirm_at', 'remark', 'leading', 'order_form_type',
        'ip', 'belongs', 'offer_elements', 'sys_type', 'cp_money','receivable_type','receivable_at', 'buyer_comment_status', 'seller_comment_status','trade_no'
    ];

    //标记订单状态改变
    protected static $mark_order_status;

    //订单状态
    const ORDER_STATUS_DELAY = 1; //等待付款
    const ORDER_STATUS_FINISH = 2; //付款完成
    const ORDER_STATUS_DELIVER = 3; //已发货
    const ORDER_STATUS_AFFIRM = 4; //确认完成
    const ORDER_STATUS_CANCEL = 5; //已取消

    //买家评价状态
    const BUYER_COMMENT_STATUS_UNDO = 0;
    const BUYER_COMMENT_STATUS_COMPLETED = 1;

    //卖家评价状态
    const SELLER_COMMENT_STATUS_UNDO = 0;
    const SELLER_COMMENT_STATUS_COMPLETED = 1;

    const RECEIVABLE_TYPE_NONE = 1;
    const RECEIVABLE_TYPE_RECEIVED = 2;

    //交易状态映射
    public static $order_status_map = [
        1 => '等待付款',
        2 => '付款完成',
        3 => '已发货',
        4 => '确认完成',
        5 => '已取消',
    ];

    //交易类型映射
    public static $order_type_map = [
        1 => '商品订单',
        2 => '库品订单',
        4 => '配单',
        5 => '限时折扣订单'
    ];

    //未发货-退款状态映射
    public static $refund_status_map = [
        0 => '无退款',
        1 => '申请退款',
        2 => '同意退款',
        3 => '不同意退款',
        4 => '退款完成'
    ];

    //退货状态映射
    public static $sales_return_status_map = [
        0 => '无退货',
        1 => '申请退货',
        2 => '同意退货',
        3 => '不同意退货',
        4 => '退货完成'
    ];

    //支付状态映射
    public static $pay_status_map = [
        0 => '未支付',
        1 => '已付款'
    ];

    //是否索取发票映射
    public static $is_claim_invoice_map = [
        0 => '不开发票',
        1 => '开发票'
    ];

    //导入标识映射
    public static $leading_map = [
        0 => '正常',
        1 => '为导入'
    ];

    //订单类型常量
    const ORDER_FORM_TYPE_FORMAL = 1;
    const ORDER_FORM_TYPE_SCALP = 2;
    const ORDER_FORM_TYPE_TEST = 3;

    //订单类型映射
    public static $order_form_type_map = [
        1 => '普通订单',
        2 => '刷单订单',
        3 => '测试订单'
    ];

    //系统操作
    public static $sys_type_map = [
        0 => '为无系统操作',
        1 => '为系统自动取消',
        2 => '为系统自动收货'
    ];

    //卖家取消原因映射
    public static $cancel_reason_map = [
        1 => '买家不买',
        2 => '订单信息填错，需要重拍',
        3 => '缺货',
        4 => '同城见面交易',
        5 => '拍错了',
        99 => '其它原因',
    ];

    //买家取消原因映射
    public static $buyer_cancel_reason_map = [

    ];

    public static function boot()
    {
        self::creating(function ($order) {
            //订单编号: 年(后2位)+月+日+店铺id（6位，前置补0）+6位流水 （如180315XXXXX000001）
            //店铺id左边补0至6位
            $shop_id_str = sprintf('%06s', $order->shop_id);
            //店铺订单流水号，自增，取后6位
            $shop_order_serial = Redis::INCR('shop:order:serial:' . $order->shop_id) % 1000000;
            $shop_order_serial_fill = sprintf('%06s', $shop_order_serial);
            $order->order_code = date('ymd') . $shop_id_str . $shop_order_serial_fill;

            $order->order_at = date('Y-m-d H:i:s', time());
        });

        self::updated(function($order){
            //放款
            if(self::$mark_order_status == self::ORDER_STATUS_AFFIRM && $order->order_status == self::ORDER_STATUS_AFFIRM){
                $receiveing_account = $order->receivingAccount()->first();
                if($receiveing_account){
                    $czbank_no = $receiveing_account->czbank_no;
                    $czbank_service = new CzbankService();
                    $ret = $czbank_service->loan($order->trade_no, $czbank_no, $order->order_money);
                    if($ret){
                        $order->receivable_type = self::RECEIVABLE_TYPE_RECEIVED;
                        $order->update();
                    }
                    //@todo 成功后记入数据库
                }
            }
        });

        parent::boot(); // TODO: Change the autogenerated stub
    }

    public function getOrderStatusNameAttribute()
    {
        if (isset($this->attributes['order_status'])) {
            return array_get(self::$order_status_map, $this->attributes['order_status']) ?: '-';
        }
        return null;
    }

    public function getIsClaimInvoiceNameAttribute()
    {
        if (isset($this->attributes['is_claim_invoice'])) {
            return array_get(self::$is_claim_invoice_map, $this->attributes['is_claim_invoice']) ?: '-';
        }
        return null;
    }

    //修改订单状态
    public function setOrderStatusAttribute($val)
    {
        if ($val == self::ORDER_STATUS_DELAY && !isset($this->attributes['order_status'])) {
            //创建订单
            $this->attributes['order_at'] = date('Y-m-d H:i:s', time());
        } elseif ($val == self::ORDER_STATUS_FINISH && $this->attributes['order_status'] == self::ORDER_STATUS_DELAY) {
            //支付完成
            $this->attributes['order_status'] = self::ORDER_STATUS_FINISH;
            $this->attributes['pay_at'] = date('Y-m-d H:i:s', time());
        } elseif ($val == self::ORDER_STATUS_DELIVER && $this->attributes['order_status'] == self::ORDER_STATUS_FINISH) {
            //发货完成
            $this->attributes['order_status'] = self::ORDER_STATUS_DELIVER;
            $this->attributes['shipments_at'] = date('Y-m-d H:i:s', time());
        } elseif ($val == self::ORDER_STATUS_AFFIRM && $this->attributes['order_status'] == self::ORDER_STATUS_DELIVER) {
            //确认收货
            $this->attributes['order_status'] = self::ORDER_STATUS_AFFIRM;
            $this->attributes['confirm_at'] = date('Y-m-d H:i:s', time());
            self::$mark_order_status = self::ORDER_STATUS_AFFIRM;
        } elseif ($val == self::ORDER_STATUS_CANCEL && $this->attributes['order_status'] == self::ORDER_STATUS_DELAY) {
            //取消订单：只有订单为未付款时才能够取消
            $this->attributes['order_status'] = self::ORDER_STATUS_CANCEL;
            $this->attributes['cancel_at'] = date('Y-m-d H:i:s', time());
        } else {
            throw new ModelNotFoundException();
        }
    }

    //修改买家评价状态
    public function setBuyerCommentStatusAttribute($val)
    {
        if ($val == self::BUYER_COMMENT_STATUS_COMPLETED && $this->attributes['order_status'] == self::ORDER_STATUS_AFFIRM) {
            //评价完订单：只有订单为完成状态才能评价完成
            $this->attributes['buyer_comment_status'] = self::BUYER_COMMENT_STATUS_COMPLETED;
        }else{
            return false;
        }
    }

    //修改卖家评价状态
    public function setSellerCommentStatusAttribute($val)
    {
        if ($val == self::SELLER_COMMENT_STATUS_COMPLETED && $this->attributes['order_status'] == self::ORDER_STATUS_AFFIRM) {
            //评价完订单：只有订单为完成状态才能评价完成
            $this->attributes['seller_comment_status'] = self::SELLER_COMMENT_STATUS_COMPLETED;
        }else{
            return false;
        }
    }

    public function getCancelReasonNameAttribute()
    {
        if(isset($this->attributes['cancel_reason'])){
            return array_get(self::$cancel_reason_map, $this->attributes['cancel_reason']);
        }
        return '-';
    }

    public function user()
    {
        return $this->hasOne(User::class, 'id', 'user_id');
    }

    public function orderProducts()
    {
        return $this->hasMany(OrderProducts::class, 'order_code', 'order_code');
    }

    public function orderProductComment()
    {
        return $this->hasMany(OrderProductComment::class, 'order_code', 'order_code');
    }

    public function invoice()
    {
        return $this->hasOne(Invoices::class, 'order_code', 'order_code');
    }

    public function shop()
    {
       return $this->hasOne(Shop::class, 'sp_id', 'shop_id');
    }
//    public function shop()
//    {
//      return $this->hasOne(Company::class, 'id', 'shop_id');
//    }

    public function orderExpress()
    {
        return $this->hasOne(OrderExpress::class, 'order_code', 'order_code');
    }
    public function order_qualification()
    {
        return $this->hasOne(OrderQualification::class, 'order_code', 'order_code');
    }

    public function userContracts()
    {
        return $this->hasOne(UserContracts::class, 'order_id', 'id');
    }

    public function receivingAccount()
    {
        return $this->hasMany(ReceivingAccount::class, 'shop_id', 'shop_id');
    }

    public function items_information(){
        return $this->hasOne(ItemsInformation::class,'item_code','order_code');
    }

    public function items_products(){
        return $this->hasMany(ItemsProducts::class,'order_id','id');
    }

    /************* 非标准部分 ************/

    //获取订单字段
    public static function getOrderColumn($order_id, $column)
    {
        $order = self::getOrderFromCache($order_id);
        return array_get($order, $column);
    }

    //订单缓存
    private static function getOrderFromCache($order_id)
    {
        $order = Cache::remember("order:$order_id:order_detail", 60 * 24 * 30, function () use ($order_id){
            $order = self::query()->find($order_id);
            return $order ? $order->toArray() : [];
        });
        return $order;
    }

}